# 用户中心kratos

kratos介绍

ORY Kratos是根据云架构最佳实践构建的API优先身份和用户管理系统。它实现了几乎每个软件应用程序都需要处理的核心用例:

  • 自助登录和注册:允许最终用户使用用户名/电子邮件和密码组合,社交登录(使用Google,GitHub登录),无密码流等创建和登录帐户(我们称其为idents)
  • 多重身份验证(MFA/2FA):支持协议,例如TOTP([RFC 6238](https://tools.ietf.org/html/rfc6238)和[ IETF RFC 4226](https://tools.ietf.org/html/rfc4226)更好地称为 [Google Authenticator](https://en.wikipedia.org/wiki/Google_Authenticator))
  • 帐户验证:验证电子邮件地址,电话号码或实际地址实际上属于该身份。
  • 帐户恢复:使用"忘记密码"流,安全代码(如果丢失MKFA设备)和其他内容来恢复访问权限。
  • 个人资料和帐户管理:使用安全流程更新密码,个人详细信息,电子邮件地址,链接的社交个人资料。
  • 管理员API:导入,更新,删除身份。

# 1 代码下载

kratos源码地址下载

解压说明

把下载的源码解压后放在本地%GOPATH%/src目录下

注:GOPATH为项目的运行时的工作空间位置,GOPATH其中包含三个子目录如下

  • src 目录包含Go的源文件,它们被组织成包(每个目录都对应一个包)
  • pkg 目录包含包对象
  • bin 目录包含可执行命令

kratos存放位置

# 2 安装数据库连接环境

特别注意:从2019年12月1日开始,Buffalo和所有相关软件包都需要Go Modules,并且GOPATH不再支持使用该模块。$GOPATH$并且最低Go版本为1.13具体说明链接

# 2.1 安装环境必需的依赖项

  • 可行的Go环境
  • 已配置的$PATH环境变量,包括$GOPATH/bin。
  • 转到版本>=1.13。

# 2.2 数据库README

说明文件在%GOPATH%\src\kratos\contrib\sql\README.md 翻译如下图:

数据库迁移说明 具体Fizz语法请参考gobuffalo.io

# 2.3 pop基础安装及使用

pop 是 gobuffalo 默认的 orm 包,当然也可以在其他项目使用 pop。但是 pop 官方强调自己不是 orm,只是具备 orm 的功能。

pop主要优点

  • CRUD 操作
  • 代码定义模型
  • 用于创建,删除和修改的迁移工具
  • 数据库支持:PostgreSQL,MySQL,SQLite
  • ActiveRecord UUID 模式
  • YAML 配置
  • 易于环境变量使用
  • 创建和更新每条记录的时间戳
  • 支持事务

# 2.3.1 soda安装

大多数Golang软件包的安装都是典型的,但是我们还将安装soda实用程序,该实用程序将促进数据库迁移和模型创建。

不需要使用sqlite 3数据库支持,例如使用mysql,执行以下命令安装soda

$ go get github.com/gobuffalo/pop/...
$ go install github.com/gobuffalo/pop/soda
1
2

需要sqlite 3支持(需要GCC或等效的C编译器),执行以下命令安装:

$ go get -u -v -tags sqlite github.com/gobuffalo/pop/...
$ go install -tags sqlite github.com/gobuffalo/pop/soda
1
2

如果您不使用构建代码buffalo build,则在构建程序时还必须传递-tags sqlite给go build。

# 2.3.2 pop配置

通过YAML文件配置弹出。每个节均按环境细分,因此您可以针对每个环境进行配置。在您的项目根目录中,创建文件database.yml或者config/database.yml,或者自定义配置文件。可以通过将-e development标志传递到任何命令中来标识开发环境。

development:
  dialect: "mysql"      #数据库类型
  database: "kratos"    #数据库名称
  host: "localhost"     #数据库连接地址
  port: "3306"          #数据库连接端口号
  user: "root"          #数据库连接用户名账号
  password: "admin"     #数据库连接账号密码
1
2
3
4
5
6
7

# 2.3.3 创建模型

pop 提供一个实用工具 soda。用 soda 可以创建模型。

$ soda generate model user title:string first_name:string last_name:string bio:text -e development
v3.41.1

--> models/user.go
--> models/user_test.go
--> goimports -w models/user.go models/user_test.go
> migrations/20191225173819_create_users.up.fizz
> migrations/20191225173819_create_users.down.fizz

1
2
3
4
5
6
7
8
9

soda创建了两个文件夹:modelsmigrations。用户模型存储在其中 models/user.go,初始迁移存储在 migrations/20191225173819_create_users.up.fizz。fizz 下面会讲到如何使用。

# 2.3.4 创建数据库

1、在执行soda命令根目录下有database.yml或者config/database.yml时,并且数据库服务器正在运行,Soda可以在database.yml使用一个简单的命令在文件中创建所有数据库,如下: -e development 代表创建开发环境下的数据库,当然也可以是 test 和 production。

$ soda create -e development
1

2、在执行soda命令根目录下 没有database.yml或者config/database.yml 时,则必须指定配置文件路径创建数据库,如下

soda create -e development -c ./contrib/sql/.soda.yml
1

# 2.3.5 完成 fizz

编辑 migrations/20191225173819_create_users.up.fizz 文件,下面代码相当于创建一张user表 然后添加两条数据。 具体数据操作语法请参考gobuffalo官网

create_table("users") {
    t.Column("id", "uuid", {primary: true})
    t.Timestamps()
    t.Column("name", "string", {})
    t.Column("email", "string", {})
    t.Column("password_hash", "string", {"size":64})
    t.Column("register_time", "timestamp", {"default": null})
    t.Column("last_login_time", "timestamp", {"default": null})
}

add_index("users", "name", {"unique": true})
add_index("users", "email", {"unique": true})
1
2
3
4
5
6
7
8
9
10
11
12

# 2.3.6 运行迁移

1 在执行soda migrate命令迁移数据时,根目录下有database.yml或者config/database.yml时,并且数据库服务器正在运行,soda可以使用下面命令迁移数据库,迁移的数据表位置在执行soda命令位置的./migrations文件夹下面的所有fizz后缀的文件

soda migrate up -e development
1

2 在执行soda migrate命令迁移数据时,根目录下 没有database.yml或者config/database.yml 时,则必须指定迁移配置的yml,迁移的文件路径在自定义的yml目录的./migrations文件夹下面的所有fizz后缀的文件

soda migrate up -e development -c ./contrib/sql/.soda.yml
1

这样,我们的数据库,数据表都已经创建完成了。

# 3 Golang操作数据库说明

# 3.1 连接数据库

tx, err := pop.Connect("development")
if err != nil {
    log.Panic(err)
}
1
2
3
4

# 3.2 创建新纪录

jessica := models.User{
        Title: "Ms.", 
        FirstName: "Jessica", 
        LastName: "Jones", 
        Bio: "Private security, super hero.",
    }
    _, err = tx.ValidateAndSave(&jessica)
    if err != nil {
        log.Panic(err)
    }
1
2
3
4
5
6
7
8
9
10

# 3.3 按 ID 查询一条记录

  id := "240ec3c5-019d-4031-9c27-8a553e022297"
    frank := models.User{}
    err = tx.Find(&frank, id)
    if err != nil {
        fmt.Print("ERROR!\n")
        fmt.Printf("%v\n", err)
    } else {
        fmt.Print("Success!\n")
        fmt.Printf("%v\n", frank)
    }
1
2
3
4
5
6
7
8
9
10

# 3.4 查询所有记录

users := []models.User{}
    err = tx.All(&users)
    if err != nil {
        fmt.Print("ERROR!\n")
        fmt.Printf("%v\n", err)
    } else {
        fmt.Print("Success!\n")
        fmt.Printf("%v\n", users)
    }
1
2
3
4
5
6
7
8
9

# 3.5 模糊查询某些数据

query := tx.Where("last_name = 'Rand' OR last_name = 'Murdock'")
    users := []models.User{}
    err = query.All(&users)
    if err != nil {
        fmt.Print("ERROR!\n")
        fmt.Printf("%v\n", err)
    } else {
        fmt.Print("Success!\n")
        fmt.Printf("%v\n", users)
    }
1
2
3
4
5
6
7
8
9
10

# 3.6 更新单个记录

 query := tx.Where("title = 'Ms.'")
    users := []models.User{}
    err = query.All(&users)
    if err != nil {
        fmt.Print("ERROR!\n")
        fmt.Printf("%v\n", err)
    } else {
        for i := 0; i < len(users); i++ {
            user := users[i]
            user.Title = "Mrs."
            tx.ValidateAndSave(&user)
            fmt.Print("Success!\n")
            fmt.Printf("%v\n", user)
        }
    }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

# 3.7 更新多个记录

更新多个记录与更新单个记录非常相似

users := []models.User{}
    err = tx.All(&users)
    if err != nil {
        fmt.Print("ERROR!\n")
        fmt.Printf("%v\n", err)
    } else {
        for i := 0; i < len(users); i++ {
            user := users[i]
            user.Location = "NYC, NY"
            tx.ValidateAndSave(&user)
            fmt.Print("Success!\n")
            fmt.Printf("%v\n", user)
        }
    }
1
2
3
4
5
6
7
8
9
10
11
12
13
14

# 3.8 删除单个记录

  id := "240ec3c5-019d-4031-9c27-8a553e022297"
    frank := models.User{}
    err = tx.Find(&frank, id)
    if err != nil {
        fmt.Print("ERROR!\n")
        fmt.Printf("%v\n", err)
    } else {
        fmt.Print("Success! - Now delete it.\n")
        tx.Destroy(&frank)
    }
1
2
3
4
5
6
7
8
9
10

# 4 迁移kratos项目的数据到mysql

备注:从这里开始使用Goland编译器来操作kratos项目

# 4.1 用Navicat创建一个数据库kratos

创建数据库kratos

# 4.2 进行kratos项目数据迁移

# 4.2.1 项目路径在%GOPATH%\src\kratos\persistence\sql\

kratos项目数据迁移准备

# 4.2.2 输入以下命令,对数据库运行所有“向上”迁移

soda migrate up -e development -c ./persistence/sql/.soda.yml
1

对数据库运行所有“向上”迁移

# 4.2.3 在Navicat查看是否迁移成功

查看是否迁移成功

# 4.2.4 修改kratos的配置文件数据连接

路径在$GOPATH$\src\kratos\docs\.kratos.yaml  修改kratos的配置文件

# 5 编译kratos

1 "win+R"打开运行。
2 输入"cmd"回车进入命令提示符。
3 进入到kratos对应目录下(本机为D:\go_project\src\kratos)
4 输入go build main.go
1
2
3
4

进入到kratos对应目录

# 6 启动kratos项目

在Goland进入%GOPATH%/src/kratos目录执行以下命令启动项目

main.exe serve -c ./docs/.kratos.yaml
1

kratos项目启动成功界面

# 7 绑定前端页面

kratos前端页面地址下载

# 7.1 前端文件结构说明

kratos-ui-node

# 7.2 前端启动

若没有安装nodejs请自行百度安装

//1 下载前端依赖包
 npm i

//2 修改配置文件 kratos-selfservice-ui-node/src/config.ts
//修改对应的后端地址ip 如图7.1

//3 启动前端页面服务
npm run start 
1
2
3
4
5
6
7
8

# 8 后台数据库说明

# 8.1 邮件消息表courier_messages

字段名称 字段类型 参数说明
id char(36) 主键id
type int(11) 邮件类型
status int(11) 邮件状态
body varchar(255) 邮件主体内容
subject varchar(255) 邮件主题
recipient varchar(255) 收件人信息
created_at datetime 创建时间
updated_at datetime 修改时间

# 8.2 身份表identities

字段名称 字段类型 参数说明
id char(36) 主键id
traits_schema_id varchar(2048) 特征模式id
traits json 个性特征
created_at datetime 创建时间
updated_at datetime 修改时间

# 8.3 身份标识符

身份标识符数据表identity_credential_identifiers

字段名称 字段类型 参数说明
id char(36) 主键id
identifier varchar(255) 身份描述
identity_credential_id char(36) identity_credentials主键id
created_at datetime 创建时间
updated_at datetime 修改时间

# 8.4 身份类型

身份证类型数据表identity_credential_types

字段名称 字段类型 参数说明
id char(36) 主键id
name varchar(32) 身份名称

# 8.5 身份证数据表

身份证数据表identity_credentials

字段名称 字段类型 参数说明
id char(36) 主键id
config json 身份配置
identity_credential_type_id char(36) identity_credential_type主键id
identity_id char(36) identities外键
created_at datetime 创建时间
updated_at datetime 修改时间

# 8.6 迁移记录表

迁移记录表schema_migration

字段名称 字段类型 参数说明
version varchar(14) 迁移版本号

# 8.7 自助服务错误表

自助服务错误表selfservice_errors

字段名称 字段类型 参数说明
id char(36) 主键id
errors json 错误信息
seen_at datetime 查看时间
was_seen tinyint(1) 是否查看信息0未查看 1已查看
created_at datetime 创建时间
updated_at datetime 修改时间
csrf_token varchar(255) token数据

# 8.8 登录请求方法记录表

自助服务登录请求方法记录表selfservice_login_request_methods

字段名称 字段类型 参数说明
id char(36) 主键id
method varchar(32) 请求方法
selfservice_login_request_id char(36) selfservice_login_requests表主键id
config json 请求方法配置信息
created_at datetime 创建时间
updated_at datetime 修改时间

# 8.9 登录请求记录表

自助服务登录请求记录表selfservice_login_requests

字段名称 字段类型 参数说明
id char(36) 主键id
request_url varchar(2048) 请求的httpUrl
issued_at datetime 触发请求时间
expires_at datetime 过期时间
active_method varchar(32) 主动方法
csrf_token varchar(255) csrf令牌
created_at datetime 创建时间
updated_at datetime 修改时间

# 8.10 配置文件管理请求

自助服务配置文件管理请求数据表selfservice_profile_management_requests

字段名称 字段类型 参数说明
id char(36) 主键id
request_url varchar(2048) 请求的httpUrl
issued_at datetime 触发请求时间
expires_at datetime 过期时间
form json form表单数据
update_successful tinyint(1) 更新是否成功
identity_id char(36) identities主键id
created_at datetime 创建时间
updated_at datetime 修改时间

# 8.11 注册请求方法记录表

自助服务注册请求方法记录表selfservice_registration_request_methods

字段名称 字段类型 参数说明
id char(36) 主键id
method varchar(32) 请求方法
selfservice_registration_request_id char(36) selfservice_registration_requests表主键id
config json 请求方法配置信息
created_at datetime 创建时间
updated_at datetime 修改时间

# 8.12 注册请求记录表

自助服务注册请求记录表selfservice_registration_requests

字段名称 字段类型 参数说明
id char(36) 主键id
request_url varchar(2048) 请求的httpUrl
issued_at datetime 触发请求时间
expires_at datetime 过期时间
active_method varchar(32) 主动方法
csrf_token varchar(255) csrf令牌
created_at datetime 创建时间
updated_at datetime 修改时间

# 8.13 sessions

字段名称 字段类型 参数说明
id char(36) 主键id
issued_at datetime 触发请求时间
expires_at datetime 过期时间
authenticated_at datetime 授权时间
identity_id char(36) identities主键id
created_at datetime 创建时间
updated_at datetime 修改时间

# 9 Kratos项目swagger详解

swagger安装教程

# 9.1 项目请求API列表

点击查看项目所有请求API列表
1 Common 公用的接口
 1.1 返回登录请求的上下文 请求方式:GET 
 说明:通过ORY Kratos的Public API访问此终结点时,请确保已设置cookie,以使CSRF正常运行。
 接口:/self-service/browser/flows/requests/login?request=1234

 1.2 获取基于浏览器的配置文件管理流的请求上下文 请求方式:GET 
 说明:通过ORY Kratos的Public API访问此端点时,请确保已设置cookie,因为它们是检查身份验证会话所必需的。
 接口:/self-service/browser/flows/requests/profile

 1.3 该端点返回注册请求的上下文 请求方式:GET 
 说明:通过ORY Kratos的Public API访问此终结点时,请确保已设置cookie,以使CSRF正常运行。
 接口:/self-service/browser/flows/requests/registration

 1.4 该端点返回与面向用户的自助服务错误相关的错误。 请求方式:GET 
 接口:/self-service/errors

2  public
 2.1 该端点初始化基于浏览器的用户登录流程。 请求方式:GET 
 接口:/self-service/browser/flows/login
 说明:该端点初始化基于浏览器的用户登录流程。初始化后,浏览器将重定向至
  urls.login_ui请求ID设置为查询参数的浏览器。如果已经存在有效的用户会话,
  则浏览器将重定向到urls.default_redirect_url。

 2.2 初始化基于浏览器的注销用户流 请求方式:GET 
 接口:/self-service/browser/flows/logout 

 2.3 初始化基于浏览器的配置文件管理流程 请求方式:GET 
 接口:/self-service/browser/flows/profile 

 2.4 完成基于浏览器的配置文件管理流程 请求方式:POST 
 接口:/self-service/browser/flows/profile/update

 2.5 初始化基于浏览器的注册用户流 请求方式:GET 
 接口:/self-service/browser/flows/registration

 2.6 获取基于浏览器的登录用户流的请求上下文 请求方式:GET 
 接口:/self-service/browser/flows/requests/login 

 2.7 获取基于浏览器的配置文件管理流的请求上下文 请求方式:GET 
 接口:/self-service/browser/flows/requests/profile

 2.8 获取基于浏览器的注册用户流的请求上下文 请求方式:GET 
 接口:/self-service/browser/flows/requests/registration

 2.9 此终结点返回与面向用户的自助服务错误相关联的错误 请求方式:GET 
 接口:/self-service/errors

 2.10 检查当前HTTP会话属于谁 请求方式:GET 
 接口:/sessions/whoami


3 admin 

 3.1 列出系统中的所有标识 请求方式:GET 
 接口:/identities

 3.2 创建标识 请求方式:POST 
 接口:/identities

 3.3 获取对应的标识 请求方式:GET 
 接口:/identities/{id}

 3.4 修改对应的标识 请求方式:PUT
 接口:/identities/{id}

 3.5 删除对应的标识 请求方式:DELETE
 接口:/identities/{id}

 3.6 获取基于浏览器的登录用户流的请求上下文 请求方式:GET
 接口:/self-service/browser/flows/requests/login

 3.7获取基于浏览器的配置文件管理流的请求上下文 请求方式:GET
 接口:/self-service/browser/flows/requests/profile

 3.8 获取基于浏览器的注册用户流的请求上下文 请求方式:GET
 接口:/self-service/browser/flows/requests/registration

 3.9 获取面向用户的自助服务错误 请求方式:GET
 接口:/self-service/errors

4 health
 4.1 检查活动状态,请求方式:GET 
 接口:/health/alive

 4.2 检查准备状态,请求方式:GET 
 接口:/health/ready

5 获取服务版本 请求方式:GET 
  接口:/version 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89

# 10 测试服务

# 10.1 跳转登录页面

跳转流程说明 kratos/public/self-service/browser/flows/login

# 11 更多资料参考

Kratos源码

Kratos官网文档